package com.hp.shiro.shiroconfig;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import com.hp.shiro.model.MenuInfo;
import com.hp.shiro.model.RoleInfo;
import com.hp.shiro.model.UserInfo;
import com.hp.shiro.service.UserService;

public class MyRealm extends AuthorizingRealm {

	@Autowired
	private UserService userService;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		// null usernames are invalid
		if (principals == null) {
			throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
		}

		UserInfo user = (UserInfo) getAvailablePrincipal(principals);

		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		List<RoleInfo> roleList = user.getRoleList();
		List<MenuInfo> menuList = user.getMenuList();
		if(!roleList.isEmpty()) {
			Set<String> roleSet = roleList.stream().map(RoleInfo::getRoleCode).collect(Collectors.toSet());
			info.setRoles(roleSet);
		}
	
		if(!menuList.isEmpty()) {
			Set<String> menuSet = menuList.stream().map(MenuInfo::getMenuCode).collect(Collectors.toSet());
			info.setStringPermissions(menuSet);
			
		}
		return info;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		UsernamePasswordToken upToken = (UsernamePasswordToken) token;
		String username = upToken.getUsername();

		if (username == null) {
		    throw new AccountException("用户名为空......");
		}

		UserInfo userDB = userService.queryUser(username);

		if (userDB == null) {
		    throw new UnknownAccountException("不存在这个用户......");
		}
		//加密比对 salt = username
		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userDB, userDB.getPassword(), ByteSource.Util.bytes(username),getName());
		return info;
	}

}
